package com.dupengcheng.subject.domain.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.dupengcheng.subject.common.entity.PageResult;
import com.dupengcheng.subject.common.enums.IsDeleteEnum;
import com.dupengcheng.subject.domain.convert.SubjectInfoBOConvert;
import com.dupengcheng.subject.domain.entity.SubjectInfoBO;
import com.dupengcheng.subject.domain.entity.SubjectOptionBO;
import com.dupengcheng.subject.domain.hanler.subject.SubjectTypeHandler;
import com.dupengcheng.subject.domain.hanler.subject.SubjectTypeHandlerFactory;
import com.dupengcheng.subject.domain.service.SubjectDomainService;
import com.dupengcheng.subject.infra.basic.entity.SubjectInfo;
import com.dupengcheng.subject.infra.basic.entity.SubjectLabel;
import com.dupengcheng.subject.infra.basic.entity.SubjectMapping;
import com.dupengcheng.subject.infra.basic.service.SubjectInfoService;
import com.dupengcheng.subject.infra.basic.service.SubjectLabelService;
import com.dupengcheng.subject.infra.basic.service.SubjectMappingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SubjectDomainServiceImpl implements SubjectDomainService {


    @Resource
    private SubjectInfoService subjectInfoService;
    @Resource
    private SubjectTypeHandlerFactory subjectTypeHandlerFactory;
    @Resource
    private SubjectMappingService subjectMappingService;
    @Resource
    private SubjectLabelService labelService;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(SubjectInfoBO subjectInfoBO) {

        //先打日志、转换、然后进行选择类型、执行。

        if (log.isInfoEnabled()){
            log.info("SubjectController.add.bo:{}", JSONObject.toJSONString(subjectInfoBO));
        }
        SubjectInfo subjectInfo = SubjectInfoBOConvert.INSTANCE
                .convertBOtoInfo(subjectInfoBO);
        subjectInfo.setIsDeleted(IsDeleteEnum.UN_DELETE.getCode());
        subjectInfoService.insert(subjectInfo);
        //进行Mapping的插入

        Long subjectId = subjectInfo.getId();
        subjectInfoBO.setId(subjectId);
        List<SubjectMapping> subjectMappings=new LinkedList<>();
        for (Integer categoryId : subjectInfoBO.getCategoryIds()) {
            for (Integer labelId : subjectInfoBO.getLabelIds()) {
                SubjectMapping subjectMapping=new SubjectMapping();
                subjectMapping.setCategoryId(categoryId.longValue());
                subjectMapping.setLabelId(labelId.longValue());
                subjectMapping.setSubjectId(subjectId);
                subjectMapping.setIsDeleted(IsDeleteEnum.UN_DELETE.getCode());
                subjectMappings.add(subjectMapping);
            }
        }
        subjectMappingService.insertBatch(subjectMappings);
        //进行具体某张表的插入。
        SubjectTypeHandler handler = subjectTypeHandlerFactory.getHandler(subjectInfoBO.getSubjectType());
        handler.add(subjectInfoBO);//完成！
    }

    @Override
    public PageResult<SubjectInfoBO> query(SubjectInfoBO subjectInfoBO) {

        PageResult<SubjectInfoBO> pageResult=new PageResult<>();
        pageResult.setPageNo(subjectInfoBO.getPageNo());
        pageResult.setPageSize(subjectInfoBO.getPageSize());
        int start=(subjectInfoBO.getPageNo()-1)*subjectInfoBO.getPageSize();
        Map<String, Object> condition = BeanUtil.beanToMap(subjectInfoBO);
        condition.put("start",start);
        condition.put("end",subjectInfoBO.getPageSize());
        int count=subjectInfoService.count(condition);
        if (count == 0) {
            return pageResult;
        }

        List<SubjectInfo> subjectInfos=subjectInfoService.getPageList(condition);
        List<SubjectInfoBO> subjectInfoBOS = SubjectInfoBOConvert.INSTANCE
                .convertInfoListToBOList(subjectInfos);
        //查出LabelNames.
        for (SubjectInfoBO infoBO : subjectInfoBOS) {
            SubjectMapping subjectMapping=new SubjectMapping();
            subjectMapping.setIsDeleted(IsDeleteEnum.UN_DELETE.getCode());
            subjectMapping.setSubjectId(infoBO.getId());
            List<SubjectMapping> subjectMappings=subjectMappingService.query(subjectMapping);
            List<Long> labels = subjectMappings.stream().map(SubjectMapping::getLabelId).collect(Collectors.toList());
            List<SubjectLabel> subjectLabels=labelService.queryBatchByLabelList(labels);
            List<String> labelNames = subjectLabels.stream()
                    .map(SubjectLabel::getLabelName)
                    .collect(Collectors.toList());
            infoBO.setLabelNames(labelNames);
        }
        pageResult.setResult(subjectInfoBOS);
        pageResult.setTotal(count);
        return pageResult;
    }

    @Override
    public SubjectInfoBO querySubjectDetail(SubjectInfoBO subjectInfoBO) {

        SubjectInfo subjectInfo = subjectInfoService.queryById(subjectInfoBO.getId());
        SubjectTypeHandler handler = subjectTypeHandlerFactory.getHandler(subjectInfo.getSubjectType());
        SubjectOptionBO query = handler.query(subjectInfoBO.getId());
        SubjectInfoBO infoBO=SubjectInfoBOConvert.INSTANCE.
                convertOptionAndInfoToBO(subjectInfo,query);

        return infoBO;

    }
}
